import axios from 'axios';
import io from 'socket.io-client';
import qs from 'qs';

import { SOCKET_SERVER } from '@/config';

let IO = null;
// defaultState
const defaultState = {
    isLogout: undefined,
    msgs: [],
    unread: 0,
    users: []
};
// defaultAction
const defaultAction = {
    type: '',
    preload: {}
};
// types
const LOGOUT = 'logout';
const GETUSERMSGS = 'getusermsgs';
const GETMSG = 'getmsg';
const SETREAD = 'setread';
// action
const logoutToState = (preload = {}) => {
    return{
        type: LOGOUT,
        preload: preload
    };
};
const logout = () => dispatch => {
    axios.get('/api/logout').then((res) => {
        res = res.data;
        dispatch(logoutToState(res));
    });
};

const getUserMsgsToState = (data) => {
    return {
        type: GETUSERMSGS,
        preload: data
    }
};
const getUserMsgs = () => dispatch => {
    axios.get('/api/getUserMsgs').then((res) => {
        res = res.data;

        const sends = {
            msgs: res.info,
            users: res.other
        }

        dispatch(getUserMsgsToState(sends));
    });
};

const sendMsg = (data = {}) => dispatch => {
    IO.emit('msg', data);
};

const getMsgToState = (data) => {
    return{
        type: GETMSG,
        preload: data
    }
};

const receive = (fromId) => dispatch => {
    IO.on('receive', (msg) => {
        msg.chat_id.indexOf(fromId) > -1 && dispatch(getMsgToState(msg));
    });
};

const setReadToState = (data) => {
    return{
        type: SETREAD,
        preload: data
    }
};
const setRead = (ids = []) => dispatch => {
    axios.post('/api/setRead', qs.stringify({items:ids.join('-')})).then(res => {
        // need update three 
        // msgs, unread, db
        res.data.code === 200 && dispatch(setReadToState(ids));
    });
};

// reducer
const chatUser = (state = defaultState, action = defaultAction) => {
    let rt = null;

    switch(action.type){
        case LOGOUT:
            // stop get message when logout
            // IO.off('receive');
            rt = {...defaultState, isLogout: action.preload.code === 1004};
            break;
        case GETUSERMSGS:
            rt = {...state, msgs: action.preload.msgs, unread: action.preload.msgs.filter(v => !v.isRead).length, users: action.preload.users};
            break;
        case GETMSG:
            rt = {...state, msgs: [...state.msgs, action.preload], unread: state.unread + 1};
            break;
        case SETREAD:
            const ids = action.preload;
            const msgs = state.msgs.map(v => {
                if(ids.includes(v._id)){
                    v.isRead = true;
                } 
                return v;
            });
            
            rt = {...state, msgs: msgs, unread: msgs.filter(v => !v.isRead).length};
            break;
        default:
            rt = state;
            break;
    }

    return rt;
};


const startChatUserSocket = () => dispatch => {
    IO = io(SOCKET_SERVER);
}

const stopChatUserSocket = () => dispatch => {
    IO.close();
}

export { chatUser, logout, getUserMsgs, sendMsg, receive, setRead, startChatUserSocket, stopChatUserSocket };